package com.wty.cmims.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.wty.cmims.mapper.DoctorMapper;
import com.wty.cmims.mapper.ScheduleMapper;
import com.wty.cmims.pojo.Appointment;
import com.wty.cmims.pojo.Doctor;
import com.wty.cmims.pojo.Schedule;
import com.wty.cmims.service.AppointmentService;
import com.wty.cmims.service.DoctorService;
import com.wty.cmims.service.ScheduleService;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
@EnableScheduling
public class ScheduledTasks {
    @Autowired
    private DoctorMapper doctorMapper;
    @Autowired
    private ScheduleService scheduleService;
    @Autowired
    private AppointmentService appointmentService;

    private final SimpleDateFormat sdfDay = new SimpleDateFormat("yyyy-MM-dd");
    private final SimpleDateFormat sdfTime = new SimpleDateFormat("HH:mm:ss");
    private final SimpleDateFormat sdfDateTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    @Scheduled(cron = "0 0 12 * * ?")
    public void scheduledTask() {
        System.out.println("每天中午12点执行的定时任务");

        // 更新一周内所有医生的排班信息
        // 1. 获取所有医生，给所有医生添加一周的排班信息，如果医生和排班日期都已存在则不添加

        // 获取所有医生ID
        LambdaQueryWrapper<Doctor> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(Doctor::getUserId);
        List<Integer> doctorIds = doctorMapper.selectObjs(wrapper).stream()
                                .map(obj -> (Integer) obj)
                                .collect(Collectors.toList());

        Map<String, Object> paramsMap = new HashMap<>();
        // 获取一周内的日期
        List<String> dates = new ArrayList<>();
        LocalDate today = LocalDate.now();
        for (int i = 0; i < 7; i++) {
            String date = today.plusDays(i).toString();
            dates.add(date);
        }

        // 遍历日期
        for (String date : dates) {
            paramsMap.put("date", date);
            // 遍历医生
            for (Integer doctorId : doctorIds) {
                paramsMap.put("doctor_id", doctorId);
                List<Schedule> schedules = scheduleService.listByMap(paramsMap);
                if (schedules.isEmpty()) {
                    // 如果该医生没有该日排班信息，添加排班信息
                    for (int i = 0; i < 4; i++) {
                        String startTime = null;
                        String endTime = null;
                        Integer rest = null;
                        Schedule schedule = new Schedule();
                        schedule.setDoctorId(doctorId);
                        try {
                            schedule.setDate(sdfDay.parse(date));
                            switch (i) {
                                case 0:
                                    startTime = "08:00:00";
                                    endTime = "10:00:00";
                                    rest = 12;
                                    break;
                                case 1:
                                    startTime = "10:00:00";
                                    endTime = "11:30:00";
                                    rest = 9;
                                    break;
                                case 2:
                                    startTime = "14:00:00";
                                    endTime = "16:00:00";
                                    rest = 12;
                                    break;
                                case 3:
                                    startTime = "16:00:00";
                                    endTime = "17:30:00";
                                    rest = 9;
                            }
                            schedule.setStartTime(sdfTime.parse(startTime));
                            schedule.setEndTime(sdfTime.parse(endTime));
                            schedule.setRest(rest);
                            boolean save = scheduleService.save(schedule);
                            if (save) {
                                System.out.println("排班信息添加成功");
                            } else {
                                System.out.println("排班信息添加失败");
                            }
                        } catch (ParseException e) {
                            System.out.println("日期格式转换异常");
                        }
                    }
                }
            }
        }
    }


    @Scheduled(cron = "0 0,30 * * * ?")
    public void updateIsOverdue() {
        // 检查日期和结束时间是否已过期，如果已过期给已过期字段赋1
        List<Schedule> allSchedules = scheduleService.list();
        allSchedules.forEach(schedule -> {
            try {
                String endDateTimeStr = sdfDay.format(schedule.getDate()) + " " + sdfTime.format(schedule.getEndTime());
                Date endDateTime = sdfDateTime.parse(endDateTimeStr);
                if (endDateTime.before(new Date())){
                    schedule.setIsOverdue(1);
                    scheduleService.updateById(schedule);
                    // 如果该排班的预约的状态不为3(完成)，则将预约状态置为4(取消)
                    LambdaUpdateWrapper<Appointment> updateWrapper = new LambdaUpdateWrapper<>();
                    updateWrapper.eq(Appointment::getScheduleId, schedule.getId())
                            .in(Appointment::getStatus, 0,1, 2)
                            .set(Appointment::getStatus, 4);
                    boolean update = appointmentService.update(updateWrapper);
                    if (update){
                        System.out.println("过期的预约状态已更新为取消");
                    }
                }
            } catch (ParseException e) {
                System.out.println("在进行过期检查时出现日期格式转换异常");
            }
        });
    }

    @PostConstruct
    public void init() {
//        scheduledTask(); // 调用定时任务方法
//        updateIsOverdue();
    }
}